{
    "metadata": {
        "kernelspec": {
            "name": "python3",
            "display_name": "Python 3"
        },
        "language_info": {
            "name": "python",
            "version": "3.6.6",
            "mimetype": "text/x-python",
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "pygments_lexer": "ipython3",
            "nbconvert_exporter": "python",
            "file_extension": ".py"
        }
    },
    "nbformat_minor": 2,
    "nbformat": 4,
    "cells": [
        {
            "cell_type": "markdown",
            "source": [
                "Create Azure SQL Virtual Machine\n",
                "============================================\n",
                "\n",
                "Steps of this procedure include:\n",
                "1. Set variables and set up Notebook \n",
                "1. Connect to Azure account and subscription \n",
                "1. Configure Network Settings \n",
                "1. Provision virtual machine resource in Azure \n",
                "1. Provision SQL VM resource in Azure"
            ],
            "metadata": {
                "azdata_cell_guid": "e479b550-d6bd-49c5-965a-34a7d1d16412"
            }
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Set variables\r\n",
                "These variables are set based on your inputs in the deployment wizard. You can make changes to these variables but be aware of possible validation errors caused by your changes.\r\n",
                "\r\n",
                "\r\n",
                "\r\n",
                "\r\n",
                ""
            ],
            "metadata": {
                "azdata_cell_guid": "37db2e50-dcde-4dd5-820c-7dc11212f1eb"
            }
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Notebook setup"
            ],
            "metadata": {
                "azdata_cell_guid": "6251b830-476f-48f2-af1e-3680b541e455"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "import sys, json, time, string, random, subprocess\n",
                "\n",
                "if \"AZDATA_NB_VAR_AZURE_SQLVM_PASSWORD\" in os.environ:\n",
                "    azure_sqlvm_password = os.environ[\"AZDATA_NB_VAR_AZURE_SQLVM_PASSWORD\"]\n",
                "\n",
                "if \"AZDATA_NB_VAR_AZURE_SQLVM_SQL_PASSWORD\" in os.environ:\n",
                "    azure_sqlvm_sqlAuthenticationPassword = os.environ[\"AZDATA_NB_VAR_AZURE_SQLVM_SQL_PASSWORD\"]\n",
                "\r\n",
                "def run_command(command, json_decode = True, printOutput = True):\n",
                "    print(command)\n",
                "    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\n",
                "    output, error = process.communicate()\n",
                "    if process.returncode != 0: \n",
                "        print(\"Process failed %d \\n%s\" % (process.returncode, error.decode(\"utf-8\")))\n",
                "        raise Exception()\n",
                "    if output:\n",
                "        output = output.decode(\"utf-8\")\n",
                "        if printOutput:\n",
                "            print(output)\n",
                "        try:\n",
                "            return json.loads(output)\n",
                "        except:\n",
                "            return output\r\n",
                "\r\n",
                "def get_random_string(length):\r\n",
                "    letters = string.ascii_lowercase\r\n",
                "    result_str = ''.join(random.choice(letters) for i in range(length))\r\n",
                "    print(\"Random string of length\", length, \"is:\", result_str)\r\n",
                "    return result_str"
            ],
            "metadata": {
                "azdata_cell_guid": "dd0caed8-b12e-4a9e-9705-fdcf5fa3ff7e",
                "tags": []
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Connecting to your Azure account\r\n",
                ""
            ],
            "metadata": {
                "azdata_cell_guid": "b06fee5e-355d-47fc-8c1f-41294756cc87"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "subscriptions = run_command('az account list', printOutput = False)\r\n",
                "if azure_sqlvm_nb_var_subscription not in (subscription[\"id\"] for subscription in subscriptions):\r\n",
                "    run_command('az login')"
            ],
            "metadata": {
                "azdata_cell_guid": "2b35980c-bb65-4ba7-95fd-7f73d8f785b5"
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Setting your Azure subscription\r\n",
                ""
            ],
            "metadata": {
                "azdata_cell_guid": "b58f1048-3e9d-4888-bda0-4d0443a11c97"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "run_command(\r\n",
                "    'az account set '\r\n",
                "    '--subscription {0}'\r\n",
                "    .format(\r\n",
                "        azure_sqlvm_nb_var_subscription));"
            ],
            "metadata": {
                "azdata_cell_guid": "0cc44e68-3810-46f4-b29c-e6ad4321e384"
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Configure network settings\r\n",
                "All networking configurations are handled in this step, including virtual network, subnet, public IP address, network security group, connectivity settings, and network interface.\r\n",
                "\r\n",
                "1. If you selected the option to create a new virtual network, subnet, or a public IP address, they will be created here. These resources are used to provide network connectivity to the virtual machine and connect it to the internet."
            ],
            "metadata": {
                "azdata_cell_guid": "202634eb-7edf-4ff4-8486-fffbda45dbc8"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "subnet_name = azure_sqlvm_subnet\r\n",
                "vnet_name = azure_sqlvm_virtnet\r\n",
                "pip_name = azure_sqlvm_publicip\r\n",
                "\r\n",
                "\r\n",
                "if azure_sqlvm_newVirtualNetwork:\r\n",
                "   run_command(\r\n",
                "      'az network vnet create '\r\n",
                "      '--resource-group {0} '\r\n",
                "      '--name {1} '\r\n",
                "      '--location {2} '\r\n",
                "      '--address-prefixes 192.168.0.0/16 '\r\n",
                "      .format(\r\n",
                "         azure_sqlvm_nb_var_resource_group_name, \r\n",
                "         vnet_name, \r\n",
                "         azure_sqlvm_location));\r\n",
                "\r\n",
                "if azure_sqlvm_newSubnet:\r\n",
                "   run_command(\r\n",
                "      'az network vnet subnet create '\r\n",
                "      '--name {0} '\r\n",
                "      '--resource-group {1} '\r\n",
                "      '--vnet-name {2} '\r\n",
                "      '--address-prefixes 192.168.1.0/24'\r\n",
                "      .format(\r\n",
                "         subnet_name,\r\n",
                "         azure_sqlvm_nb_var_resource_group_name,\r\n",
                "         vnet_name\r\n",
                "         ));\r\n",
                "\r\n",
                "if azure_sqlvm_newPublicIp:\r\n",
                "   run_command(\r\n",
                "      'az network public-ip create '\r\n",
                "      '--resource-group {0} '\r\n",
                "      '--location {1} '\r\n",
                "      '--allocation-method Static '\r\n",
                "      '--idle-timeout 4 '\r\n",
                "      '--name {2}'\r\n",
                "      .format(\r\n",
                "         azure_sqlvm_nb_var_resource_group_name, \r\n",
                "         azure_sqlvm_location, \r\n",
                "         pip_name));"
            ],
            "metadata": {
                "azdata_cell_guid": "af88cdae-1a62-4990-9231-094481c9337d"
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "2. Create a network security group and configure rules to allow remote desktop (RDP) and SQL Server connections."
            ],
            "metadata": {
                "azdata_cell_guid": "3b25e16e-b150-4a2e-80dc-66f2d18b43fb"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "nsg_name = azure_sqlvm_nb_var_resource_group_name + 'nsg'\r\n",
                "nsg_name_id = run_command(\r\n",
                "   'az network nsg create '\r\n",
                "   '--resource-group {0} '\r\n",
                "   '--location {1} '\r\n",
                "   '--name {2} '\r\n",
                "   .format(\r\n",
                "      azure_sqlvm_nb_var_resource_group_name,\r\n",
                "      azure_sqlvm_location, \r\n",
                "      nsg_name));\r\n",
                "\r\n",
                "if azure_sqlvm_allow_rdp:\r\n",
                "   run_command(\r\n",
                "      'az network nsg rule create '\r\n",
                "      '--name RDPRule '\r\n",
                "      '--nsg-name {0} '\r\n",
                "      '--priority 1000 '\r\n",
                "      '--resource-group {1} '\r\n",
                "      '--protocol Tcp '\r\n",
                "      '--direction Inbound '\r\n",
                "      '--source-address-prefixes * '\r\n",
                "      '--source-port-range * '\r\n",
                "      '--destination-address-prefixes * '\r\n",
                "      '--destination-port-range 3389  '\r\n",
                "      '--access Allow'\r\n",
                "      .format(\r\n",
                "         nsg_name,\r\n",
                "         azure_sqlvm_nb_var_resource_group_name));"
            ],
            "metadata": {
                "azdata_cell_guid": "debe940d-0d0f-4540-be5b-4d6495d338e1"
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "3. Create the network interface."
            ],
            "metadata": {
                "azdata_cell_guid": "d44de03c-d4f2-48ef-8a60-507069d6c08e"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "interface_name = azure_sqlvm_nb_var_resource_group_name + \"int\"\r\n",
                "\r\n",
                "command = (\r\n",
                "   'az network nic create '\r\n",
                "   '--name {0} '\r\n",
                "   '--resource-group {1} '\r\n",
                "   '--subnet {2} '\r\n",
                "   '--public-ip-address {3} '\r\n",
                "   '--network-security-group {4} '\r\n",
                "   '--location {5} '\r\n",
                ")\r\n",
                "\r\n",
                "if azure_sqlvm_newSubnet:\r\n",
                "   command += '--vnet-name {6} '\r\n",
                "\r\n",
                "run_command(\r\n",
                "   command\r\n",
                "   .format(\r\n",
                "      interface_name,\r\n",
                "      azure_sqlvm_nb_var_resource_group_name,\r\n",
                "      subnet_name,\r\n",
                "      pip_name,\r\n",
                "      nsg_name,\r\n",
                "      azure_sqlvm_location,\r\n",
                "      vnet_name));"
            ],
            "metadata": {
                "azdata_cell_guid": "6dbb3ea0-b52f-4ed2-bd24-59096d134e88"
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "markdown",
            "source": [
                "## Create Azure Virtual Machine and Azure SQL VM resources\r\n",
                "First the Azure VM will be created based on all the settings previously specified. Next the SQL VM will be created to include a default set of SQL connectivity settings. The SQL VM resource is where you can manage any SQL Server manageability features offered by Azure. [Learn more](https://docs.microsoft.com/azure/azure-sql/virtual-machines/windows/sql-server-on-azure-vm-iaas-what-is-overview) about what you can do with your Azure SQL VM after it has been created."
            ],
            "metadata": {
                "azdata_cell_guid": "c42ec570-331a-46ea-b358-b05e47320967"
            }
        },
        {
            "cell_type": "code",
            "source": [
                "# Create the VM\r\n",
                "azure_sqlvm_image = 'sql2019-ws2019'\r\n",
                "\r\n",
                "run_command(\r\n",
                "   'az vm create '\r\n",
                "   '--name {0} '\r\n",
                "   '--size {1} '\r\n",
                "   '--computer-name {0} '\r\n",
                "   '--admin-username {2} '\r\n",
                "   '--admin-password {3} '\r\n",
                "   '--image {4}:{5}:{6}:{7} '\r\n",
                "   '--nics {8} '\r\n",
                "   '--resource-group {9} '\r\n",
                "   '--location {10} '\r\n",
                "   .format(\r\n",
                "       azure_sqlvm_vmname,\r\n",
                "       azure_sqlvm_vmsize,\r\n",
                "       azure_sqlvm_username,\r\n",
                "       azure_sqlvm_password,\r\n",
                "       'MicrosoftSQLServer',\r\n",
                "       azure_sqlvm_image,\r\n",
                "       azure_sqlvm_image_sku,\r\n",
                "       'latest',\r\n",
                "       interface_name,\r\n",
                "       azure_sqlvm_nb_var_resource_group_name,\r\n",
                "       azure_sqlvm_location\r\n",
                "   )\r\n",
                ");"
            ],
            "metadata": {
                "azdata_cell_guid": "05fa1f3d-94e1-480f-ad20-d3006bafc6ac",
                "tags": []
            },
            "outputs": [],
            "execution_count": null
        },
        {
            "cell_type": "code",
            "source": [
                "command = (\r\n",
                "    'az sql vm create '\r\n",
                "    '--name {0} '\r\n",
                "    '--license-type PAYG '\r\n",
                "    '--resource-group {1} '\r\n",
                "    '--connectivity-type {2} '\r\n",
                "    '--sql-mgmt-type Full '\r\n",
                "    '--location {3} '\r\n",
                ")\r\n",
                "\r\n",
                "if azure_sqlvm_enableSqlAuthentication:\r\n",
                "    command += '--sql-auth-update-username {4} '\r\n",
                "    command += '--sql-auth-update-pwd {5} '\r\n",
                "\r\n",
                "if azure_sqlvm_sqlConnectivityType != 'local':\r\n",
                "    command += '--port {6} '\r\n",
                "\r\n",
                "run_command(\r\n",
                "    command\r\n",
                "    .format(\r\n",
                "        azure_sqlvm_vmname,\r\n",
                "        azure_sqlvm_nb_var_resource_group_name,\r\n",
                "        azure_sqlvm_sqlConnectivityType,\r\n",
                "        azure_sqlvm_location,\r\n",
                "        azure_sqlvm_sqlAuthenticationUsername,\r\n",
                "        azure_sqlvm_sqlAuthenticationPassword,\r\n",
                "        azure_sqlvm_port,\r\n",
                "    )\r\n",
                ");"
            ],
            "metadata": {
                "azdata_cell_guid": "bb3b5436-c34b-44b3-b631-ea60c9dcf16a"
            },
            "outputs": [],
            "execution_count": null
        }
    ]
}